package com.ly.heart.service.impl;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.ly.common.PageParam;
import com.ly.common.core.domain.ActCurrentTaskVo;
import com.ly.common.core.domain.AjaxResult;
import com.ly.common.core.domain.entity.SysDept;
import com.ly.common.exception.CustomException;
import com.ly.common.utils.DateUtils;
import com.ly.common.utils.SecurityUtils;
import com.ly.common.utils.erp.ConstUtil;
import com.ly.common.utils.erp.KingConstUtil;
import com.ly.common.utils.erp.SnowflakeIdWorker;
import com.ly.heart.domain.*;
import com.ly.heart.domain.dto.KingAssembleDto;
import com.ly.heart.domain.dto.StartProcessDto;
import com.ly.heart.domain.vo.KingAssembleVo;
import com.ly.heart.mapper.KingAssembleMapper;
import com.ly.heart.service.*;
import com.ly.heart.util.ChineseToPinyin;
import com.ly.heart.util.CurrentUserUtil;
import com.ly.system.service.ISysDeptService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;

/**
 * 金蝶-组装拆卸Service业务层处理
 * @author wutao
 * @date 2024-07-26
 */
@Service
public class KingAssembleServiceImpl extends ServiceImpl<KingAssembleMapper, KingAssembleEntity> implements IKingAssembleService {

    @Resource
    private KingAssembleMapper kingAssembleEntityMapper;
    @Resource
    private IKingAssembleDetailService iKingAssembleDetailService;
    @Resource
    private IKingInventoryService iKingInventoryService;
    @Resource
    private IKingInventoryMaterialService iKingInventoryMaterialService;
    @Resource
    private ISysDeptService iSysDeptService;
    @Resource
    private IMaterialService iMaterialService;
    @Resource
    private IWarehouseService iWarehouseService;
    @Resource
    private IActModelService iActModelService;
    @Resource
    private IActTaskCommentService iActTaskCommentService;
    @Resource
    private ICustomerService iCustomerService;
    @Resource
    private ISupplierService iSupplierService;

    /**
     * 查询金蝶-组装拆卸
     * @param id 金蝶-组装拆卸ID
     * @return 金蝶-组装拆卸
     */
    @Override
    public KingAssembleVo selectKingAssembleEntityById (String id) {
        KingAssembleVo vo = new KingAssembleVo ();
        KingAssembleEntity kingAssembleEntity = kingAssembleEntityMapper.selectKingAssembleEntityById ( id );
        if ( kingAssembleEntity == null ) {
            return null;
        }
        String productShipper = getProductShipper ( kingAssembleEntity.getProductShipperType (), kingAssembleEntity.getProductShipperCode () );
        kingAssembleEntity.setProductShipperName ( productShipper );
        String childShipperCodeName = getProductShipper ( kingAssembleEntity.getChildShipperType (), kingAssembleEntity.getProductShipperCode () );
        kingAssembleEntity.setChildShipperCodeName ( childShipperCodeName );
        KingAssembleDetailEntity detailEntity = new KingAssembleDetailEntity();
        detailEntity.setAssembleId ( id );
        List<KingAssembleDetailEntity> list = iKingAssembleDetailService.selectKingAssembleDetailEntityList ( detailEntity );
        List<KingAssembleDetailEntity> parent = list.stream ().filter ( detail -> detail.getType () == 1 ).collect ( Collectors.toList () );
        List<KingAssembleDetailEntity> child = list.stream ().filter ( detail -> detail.getType () == 2 ).collect ( Collectors.toList () );
        vo.setKingAssembleEntity ( kingAssembleEntity ).setKingAssembleDetailParentEntities ( parent ).setKingAssembleDetailChildEntities ( child );
        return vo;
    }

    /**
     * 查询金蝶-组装拆卸列表
     * @param kingAssembleEntity 金蝶-组装拆卸
     * @return 金蝶-组装拆卸
     */
    @Override
    public AjaxResult selectKingAssembleEntityList (KingAssembleEntity kingAssembleEntity) {
        kingAssembleEntity.setIsUsed ( ConstUtil.IS_USED_YES );
        kingAssembleEntity.setPage ( ( kingAssembleEntity.getPage () - 1 ) );
        List<KingAssembleEntity> kingAssembleEntities = kingAssembleEntityMapper.selectKingAssembleEntityList ( kingAssembleEntity );
        kingAssembleEntities.forEach ( assemble -> {
            //处理最后一个审批人
            ActTaskCommentEntity actTaskCommentEntity = iActTaskCommentService.queryLastComment ( assemble.getInstanceId () );
            if ( actTaskCommentEntity != null ) {
                assemble.setApprovedUser ( actTaskCommentEntity.getApprovedUser () );
                assemble.setApprovedRemark ( actTaskCommentEntity.getRemark () );
            }
            //任务信息
            ActCurrentTaskVo currentTaskVo = iActModelService.getCurrentTaskByInstanceId ( assemble.getInstanceId () );
            Optional.ofNullable ( currentTaskVo ).ifPresent ( currentTask -> {
                assemble.setCurrentTask ( currentTask );
            } );
        } );
        PageParam p = new PageParam ();
        p.setTotal ( kingAssembleEntityMapper.queryCount ( kingAssembleEntity ) ).setRecords ( kingAssembleEntities ).setCurrent ( kingAssembleEntity.getPage () );
        return AjaxResult.success ( p );
    }

    /**
     * 新增金蝶-组装拆卸
     * @param kingAssembleDto 金蝶-组装拆卸
     * @return 结果
     */
    @Override
    @Transactional (rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public AjaxResult draft (KingAssembleDto kingAssembleDto) {
        KingAssembleEntity kingAssembleEntity = kingAssembleDto.getKingAssembleEntity ();
        kingAssembleEntity.setId ( SnowflakeIdWorker.getInstance ().nextStringId () );
        int count = this.count ();
        String py = ChineseToPinyin.getFirstLetter ( "组装拆卸单" );
        String format = String.format ( "%08d", count );
        kingAssembleEntity.setDocNo ( py.concat ( format ) );
        kingAssembleEntity.setCreateUser ( SecurityUtils.getLoginUser ().getUser ().getUserId () );
        kingAssembleEntity.setCreateDate ( DateUtils.getNowDate () );
        updateAssembleDetail ( kingAssembleDto.getKingAssembleDetailEntities (), kingAssembleEntity.getId () );
        kingAssembleEntity.setState ( ConstUtil.STATE_IN_DRAFT );
        boolean save = this.save ( kingAssembleEntity );
        if ( ! save ) {
            throw new CustomException ( "暂存装拆卸失败！" );
        }
        return AjaxResult.success ( "暂存装拆卸成功", kingAssembleEntity.getId () );
    }

    /**
     * 新增金蝶-组装拆卸
     * @param kingAssembleEntity 金蝶-组装拆卸
     * @return 结果
     */
    @Override
    @Transactional (rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public AjaxResult submit (KingAssembleEntity kingAssembleEntity) {
        StartProcessDto startDto = new StartProcessDto ().
                setBusinessId ( kingAssembleEntity.getId () ).
                setBusinessType ( kingAssembleEntity.getBusinessType () ).setModelId ( kingAssembleEntity.getModelId () ).
                setBusinessName ( "组装拆卸单".concat ( kingAssembleEntity.getId () ) );
        String instanceId = iActModelService.startProcess ( startDto );
        boolean save = this.update ( new LambdaUpdateWrapper<KingAssembleEntity> ().
                set ( KingAssembleEntity :: getInstanceId, instanceId ).
                set ( KingAssembleEntity :: getState, ConstUtil.STATE_IN_PROCESS ).
                eq ( KingAssembleEntity :: getId, kingAssembleEntity.getId () ) );
        if ( ! save ) {
            throw new CustomException ( "提交组装拆卸失败！" );
        }
        return AjaxResult.success ();
    }

    /**
     * 修改金蝶-组装拆卸
     * @param kingAssembleDto 金蝶-组装拆卸
     * @return 结果
     */
    @Override
    public AjaxResult updateKingAssembleEntity (KingAssembleDto kingAssembleDto) {
        KingAssembleEntity kingAssembleEntity = kingAssembleDto.getKingAssembleEntity ();
        kingAssembleEntity.setUpdateDate ( DateUtils.getNowDate () );
        kingAssembleEntity.setUpdateUser ( SecurityUtils.getLoginUser ().getUser ().getUserId () );
        updateAssembleDetail ( kingAssembleDto.getKingAssembleDetailEntities (), kingAssembleEntity.getId () );
        boolean b = this.updateById ( kingAssembleEntity );
        if ( ! b ) {
            throw new CustomException ( "修改组装拆卸基本信息失败！" );
        }
        return AjaxResult.success ();
    }

    /**
     * 批量删除金蝶-组装拆卸
     * @param ids 需要删除的金蝶-组装拆卸ID
     * @return 结果
     */
    @Override
    public int deleteKingAssembleEntityByIds (String[] ids) {
        return kingAssembleEntityMapper.deleteKingAssembleEntityByIds ( ids );
    }

    /**
     * 数据伪删除
     * @param ids 金蝶-组装拆卸ID
     * @return
     */
    @Override
    @Transactional (rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public AjaxResult updateByDelete (String[] ids) {
        KingAssembleEntity kingAssembleEntity = new KingAssembleEntity ();
        for ( int i = 0; i < ids.length; i++ ) {
            kingAssembleEntity.setId ( ids[i] );
            kingAssembleEntity.setIsUsed ( ConstUtil.IS_USED_NO );
            int update = kingAssembleEntityMapper.updateKingAssembleEntity ( kingAssembleEntity );
            if ( update == 0 ) {
                throw new CustomException ( "删除组装拆卸单失败！" );
            }
        }
        // 更新明细
        LambdaUpdateWrapper<KingAssembleDetailEntity> detailUpdate = new LambdaUpdateWrapper<> ();
        detailUpdate.set ( KingAssembleDetailEntity :: getIsUsed, ConstUtil.IS_USED_NO );
        detailUpdate.in ( KingAssembleDetailEntity :: getAssembleId, ids );
        iKingAssembleDetailService.update ( detailUpdate );
        return AjaxResult.success ( "删除组织拆卸成功" );
    }

    /**
     * 组装拆卸审批后业务处理
     * 组装：子项减少，父项增加；即添加一条子项的出库记录，父项的入库记录
     * 拆卸：父项减少，子项增加；即添加一条父项的出库记录，子项的入库记录
     * @param id
     */
    @Transactional (rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public AjaxResult approve (String id) {
        KingAssembleEntity assembleEntity = this.getById ( id );
        if ( assembleEntity == null ) {
            throw new CustomException ( "该单据不存在！" );
        }
        SysDept sysDept = iSysDeptService.getById ( CurrentUserUtil.getCompanyId () );
        String firstLetter = ChineseToPinyin.getFirstLetter ( sysDept.getDeptName () );
        //父与子列表
        List<KingAssembleDetailEntity> list = iKingAssembleDetailService.list ( new LambdaQueryWrapper<KingAssembleDetailEntity> ().eq ( KingAssembleDetailEntity :: getAssembleId, id ) );
        //封装父物料对象
        KingInventoryEntity parentEntity = new KingInventoryEntity ();
        parentEntity.setId ( SnowflakeIdWorker.getInstance ().nextStringId () ).setCreateTime ( DateUtils.getNowDate () ).setUserId ( SecurityUtils.getLoginUser ().getUser ().getUserId () ).setReceivingOrg ( CurrentUserUtil.getCompanyId () ).setPurchaseOrg ( CurrentUserUtil.getCompanyId () ).setInvalidTime ( DateUtils.getNowDate () );
        //封装子物料对象
        KingInventoryEntity childEntity = new KingInventoryEntity ();
        childEntity.setId ( SnowflakeIdWorker.getInstance ().nextStringId () ).setCreateTime ( DateUtils.getNowDate () ).setUserId ( SecurityUtils.getLoginUser ().getUser ().getUserId () ).setReceivingOrg ( CurrentUserUtil.getCompanyId () ).setPurchaseOrg ( CurrentUserUtil.getCompanyId () ).setInvalidTime ( DateUtils.getNowDate () );
        int inCount = iKingInventoryService.count ( new LambdaQueryWrapper<KingInventoryEntity> ().eq ( KingInventoryEntity :: getType, 0 ) );
        String inFormat = String.format ( "%06d", inCount );
        int outCount = iKingInventoryService.count ( new LambdaQueryWrapper<KingInventoryEntity> ().eq ( KingInventoryEntity :: getType, 1 ) );
        String ouFormat = String.format ( "%06d", outCount );
        if ( KingConstUtil.TRANSACTION_TYPE_ASSEMBLE.equals ( assembleEntity.getTransactionType () ) ) {
            //组装：子项列表出库，父项列表入库；组装拆卸单的子件明细出库，产品明细入库
            parentEntity.setDocCode ( firstLetter.concat ( "_CGRK_".concat ( inFormat ) ) ).setType ( "0" ).setChildTye ( "1" );
            //拆卸：父项列表出库，子项列表入库；组装拆卸单的差评明细出库，子件明细入库
            childEntity.setDocCode ( firstLetter.concat ( "_XSCK_".concat ( ouFormat ) ) ).setType ( "1" );
        } else if ( KingConstUtil.TRANSACTION_TYPE_DISASSEMBLE.equals ( assembleEntity.getTransactionType () ) ) {
            //拆卸：父项减少，子项增加；即添加一条父项的出库记录，子项的入库记录
            childEntity.setDocCode ( firstLetter.concat ( "_CGRK_".concat ( inFormat ) ) ).setType ( "0" ).setChildTye ( "1" );
            //拆卸：父项列表出库，子项列表入库；组装拆卸单的差评明细出库，子件明细入库
            parentEntity.setDocCode ( firstLetter.concat ( "_XSCK_".concat ( ouFormat ) ) ).setType ( "1" );
        }
        boolean saveParent = iKingInventoryService.save ( parentEntity );
        boolean saveChild = iKingInventoryService.save ( childEntity );
        if ( ! saveParent || ! saveChild ) {
            throw new CustomException ( "组装拆卸单生成出入库失败！" );
        }
        list.forEach ( detail -> {
            KingInventoryMaterialEntity inventoryMaterialEntity = new KingInventoryMaterialEntity ();
            inventoryMaterialEntity.setId ( SnowflakeIdWorker.getInstance ().nextStringId () );
            inventoryMaterialEntity.setMaterialCode ( detail.getMaterialCode () );
            inventoryMaterialEntity.setInventoryUnit ( detail.getMaterialUnit () );
            MaterialEntity one = iMaterialService.getOne ( new LambdaQueryWrapper<MaterialEntity> ().eq ( MaterialEntity :: getMaterialCode, detail.getMaterialCode () ) );
            inventoryMaterialEntity.setMaterialId ( one.getId () );
            inventoryMaterialEntity.setMaterialModel ( one.getModel () );
            inventoryMaterialEntity.setMaterialDesc ( one.getMaterialDesc () );
            inventoryMaterialEntity.setReceivableNum ( detail.getNum () );
            inventoryMaterialEntity.setReceiptsNum ( detail.getNum () );
            inventoryMaterialEntity.setPricingUnit ( one.getUnit () );
            inventoryMaterialEntity.setPricingNum ( detail.getNum () );
            inventoryMaterialEntity.setBatchNum ( detail.getBatchNo () );
            inventoryMaterialEntity.setBusinessTaxPrice ( detail.getFee () );
            WarehouseEntity warehouseEntity = iWarehouseService.getOne ( new LambdaQueryWrapper<WarehouseEntity> ().eq ( WarehouseEntity :: getWareCode, detail.getWarehouseCode () ) );
            inventoryMaterialEntity.setWarehouseId ( warehouseEntity.getId () );
            inventoryMaterialEntity.setWarehouseCode ( detail.getWarehouseCode () );
            inventoryMaterialEntity.setWarehousePosition ( detail.getWarehousePosition () );
            inventoryMaterialEntity.setRemark ( "组装拆卸单生成" );
            inventoryMaterialEntity.setCreateTime ( DateUtils.getNowDate () );
            inventoryMaterialEntity.setUserId ( SecurityUtils.getLoginUser ().getUser ().getUserId () );
            //父与子都有，根据type区分
            inventoryMaterialEntity.setInventoryId ( detail.getType () == 1 ? parentEntity.getId () : childEntity.getId () );
            boolean save = iKingInventoryMaterialService.save ( inventoryMaterialEntity );
            if ( ! save ) {
                throw new CustomException ( "组装拆卸单生成出入库明细失败！" );
            }
        } );
        return AjaxResult.success ();
    }


    /**
     * 更新自制拆卸明细
     * @param kingAssembleDetailEntities
     * @param assembleId
     */
    private void updateAssembleDetail (List<KingAssembleDetailEntity> kingAssembleDetailEntities, String assembleId) {
        if ( ! CollectionUtils.isEmpty ( kingAssembleDetailEntities ) ) {
            iKingAssembleDetailService.remove ( new LambdaUpdateWrapper<KingAssembleDetailEntity> ().eq ( KingAssembleDetailEntity :: getAssembleId, assembleId ) );
            kingAssembleDetailEntities.forEach ( detail -> {
                detail.setId ( SnowflakeIdWorker.getInstance ().nextStringId () );
                detail.setAssembleId ( assembleId );
                detail.setCreateUser ( SecurityUtils.getLoginUser ().getUser ().getUserId () );
                detail.setCreateDate ( DateUtils.getNowDate () );
                boolean save = iKingAssembleDetailService.save ( detail );
                if ( ! save ) {
                    throw new CustomException ( "更新组装拆卸明细失败" );
                }
            } );
        }
    }

    /**
     * 根据成品货主类型，查询成品货主
     * BD_OwnerOrg：业务组织；BD_Supplier：供应商；BD_Customer：客户
     * @param productShipperType
     * @return
     */
    private String getProductShipper (String productShipperType, String productShipperCode) {
        String transactionCompany = "";
        switch ( productShipperType ) {
            case "BD_Customer":
                CustomerEntity customerEntity = iCustomerService.getOne ( new LambdaQueryWrapper<CustomerEntity> ().eq ( CustomerEntity :: getCustomerCode, productShipperCode ) );
                if ( customerEntity != null )
                    transactionCompany = customerEntity.getCustomerName ();
                break;
            case "BD_Supplier":
                SupplierEntity supplierEntity = iSupplierService.getOne ( new LambdaQueryWrapper<SupplierEntity> ().eq ( SupplierEntity :: getSupplierCode, productShipperCode ) );
                if ( supplierEntity != null )
                    transactionCompany = supplierEntity.getSupplierName ();
                break;
            case "BD_OwnerOrg":
                SysDept organ = iSysDeptService.getOne ( new LambdaQueryWrapper<SysDept> ().eq ( SysDept :: getDeptCode, productShipperCode ) );
                if ( organ != null )
                    transactionCompany = organ.getDeptName ();
                break;
        }
        return transactionCompany;
    }

}
